# encoding: utf-8
from jsonrpc import ServiceMethod

from subprocess import Popen, PIPE
from threading import Lock, Thread
import shlex, sys
import datetime, time
import tempfile

class API(object):
    def __init__(self, max_execution_time, logger):
        self.logger=logger
        self.max_execution_time = max_execution_time
    
    @ServiceMethod
    def ping(self):
        return 'OK'
    
    @ServiceMethod
    def exec_shell(self, command, timeout, max_result = 1024*1024):
        if sys.platform == 'win32':
            args = command
        else:
            args = command
        return self.exec_command(args, timeout, max_result, True)
    
    @ServiceMethod
    def exec_command(self, args, timeout, max_result = 1024*1024, shell=False):
        self.logger.info('Command: ' + str(args))
        try:
            f_out = tempfile.TemporaryFile()
            f_err = tempfile.TemporaryFile()
            
            timeout = min(timeout, self.max_execution_time)
            
            p = Popen(args, shell=shell, stdout=f_out, stderr=f_err, stdin=PIPE)
            
            if timeout == -1:
                p.wait()
            else:
                timeout = datetime.timedelta(0, timeout)
                start = datetime.datetime.now()
                while datetime.datetime.now() - start < timeout:
                    if p.poll() == None:
                        time.sleep(1)
                    else:
                        break
                    
                if datetime.datetime.now() - start >= timeout:
                    try:
                        p.kill()
                    except Exception:
                        pass
                
                p.wait()
                f_out.seek(0)
                data = f_out.read(max_result)    
                
                f_out.close()
                f_err.close()
                
                res = {}
                res['code'] = p.poll()
                res['stdout64'] = data.encode('base64')
                self.logger.debug('Result: ' + str(res))
                return res
        except Exception, ex:
            self.logger.warning('Exception: ' + str(ex))
            raise ex